package com.parser.resume;

import java.io.BufferedReader;
import java.io.DataInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import opennlp.tools.cmdline.PerformanceMonitor;
import opennlp.tools.cmdline.postag.POSModelLoader;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.WhitespaceTokenizer;
import util.CollectionUtils;
import util.DiceCoefficient;

import com.parser.interfaces.IResumeParser;

public class ResumeParser extends CollectionUtils implements IResumeParser {
	String id;
	String resume, keywords;
	List<String> emails = new ArrayList<String>();
	List<String> phoneNumbers = new ArrayList<String>();
	List<String> name = new ArrayList<>();
	List<String> headings = new ArrayList<String>();
	List<Integer> headingIndexes = new ArrayList<Integer>();
	HashMap<String, String> layOuts = new HashMap<String, String>();
	String[] resumeArray, keyWordsList;
	POSTaggerME tagger;

	@SuppressWarnings("resource")
	public ResumeParser(String filepath) {
		id = UUID.randomUUID().toString();
		try {
			FileInputStream fstream = new FileInputStream(filepath);
			DataInputStream in = new DataInputStream(fstream);
			BufferedReader br = new BufferedReader(new InputStreamReader(in));
			String strLine;
			POSModel model = new POSModelLoader().load(new File(
					"src\\util\\en-pos-maxent.bin"));
			PerformanceMonitor perfMon = new PerformanceMonitor(System.err,
					"sent");
			tagger = new POSTaggerME(model);

			while ((strLine = br.readLine()) != null) {
				resume += strLine + "\n";
			}
			resume = resume.substring(resume.indexOf("<Content>") + 9,
					resume.indexOf("</Content>"));
			if (resume.indexOf("\nResume") > 0)
				resume = resume.substring(resume.indexOf("\nResume"));
			resumeArray = resume.split("\n");

			fstream = new FileInputStream(
					"src\\util\\resumeKeywords.txt");
			in = new DataInputStream(fstream);
			br = new BufferedReader(new InputStreamReader(in));
			while ((strLine = br.readLine()) != null) {
				keywords += strLine + "\n";
			}
			keyWordsList = keywords.split("\n");
			fstream.close();
			br.close();
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	public List<String> getEmailAddresses() {
		try {
			Pattern pattern = Pattern.compile(RegexConfig.EMAIL_PATTREN);
			Matcher matcher = pattern.matcher(resume);
			while (matcher.find()) {
				emails.add(matcher.group());
			}
			emails = removeDuplicates(emails);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return emails;
	}

	public List<String> getPhoneNumbers() {
		resume = resume.replaceAll(RegexConfig.DATE_PATTERN, "")
				.replaceAll(RegexConfig.DATE_PATTERN1, "")
				.replaceAll(RegexConfig.YEAR_PATTREN, "");
		Pattern pattern = Pattern.compile(RegexConfig.PHONE_NUMBER_PATTREN);
		Matcher matcher = pattern.matcher(resume);
		while (matcher.find()) {
			phoneNumbers.add(matcher.group().replaceAll("[^\\d]", ""));
		}
		phoneNumbers = removeDuplicates(phoneNumbers);
		for (String i : phoneNumbers) {
			for (String j : phoneNumbers) {
				if (phoneNumbers.indexOf(i) != phoneNumbers.indexOf(j)) {
					int c = i.indexOf(j);
					if (c != -1) {
						phoneNumbers.set(phoneNumbers.indexOf(j), "");
					}
				}
			}
			if (phoneNumbers.indexOf(i) == phoneNumbers.size() - 1) {
				break;
			}
		}
		for (int i = 0; i < phoneNumbers.size(); i++) {
			if (!phoneNumbers.get(i).equals("")
					&& phoneNumbers.get(i).length() > 9) {

			}
		}
		return phoneNumbers;
	}

	public HashMap<String, String> getLayouts() {
		try {
			for (int i = 0; i < resumeArray.length; i++) {
				resumeArray[i] = resumeArray[i] + "\n";
				for (int j = 0; j < keyWordsList.length; j++) {
					if (!keyWordsList[j].equals("") && keyWordsList[j] != null) {
						String keyWordPat = "^\\s*[a-z]* *" + keyWordsList[j]
								+ " *[a-z| ]*[:|\n|	]";
						Pattern pattern = Pattern.compile(keyWordPat,
								Pattern.CASE_INSENSITIVE);
						Matcher matcher = pattern.matcher(resumeArray[i]);
						if (matcher.find()) {
							if (resumeArray[i].trim().matches(
									RegexConfig.CAPITAL_LETTER_PATTREN
											+ RegexConfig.CONTENT_PATTREN)) {
								headingIndexes.add(i);
							}
							if (resumeArray[i].trim().matches(
									RegexConfig.TITLE_CASE_PATTREN
											+ RegexConfig.CONTENT_PATTREN)) {
								headingIndexes.add(i);
							}
						}
					}
				}
			}
			System.out.println(headingIndexes);
			headingIndexes = removeDuplicates(headingIndexes);
			System.out.println(headingIndexes);
			Collections.sort(headingIndexes);
			for (int i = 0; i < headingIndexes.size(); i++) {
				String value = "";
				int limit;
				if (i == headingIndexes.size() - 1) {
					limit = resumeArray.length;
				} else {
					limit = headingIndexes.get(i + 1) - 1;
				}
				for (int j = headingIndexes.get(i) + 1; j < limit; j++) {
					value = value + resumeArray[j].trim()+"\n";
				}
				String key = resumeArray[headingIndexes.get(i)]
						.split("[:|\n|	|-]")[0].trim();
				layOuts.put(key, value.replaceAll(key, ""));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		Set<String> keyset = layOuts.keySet();
		for (String keyval : keyset) {
			System.out.println(keyval + ":" + layOuts.get(keyval));
			System.out.println("******************************");
		}
		return layOuts;
	}

	public List<String> getName() {
		try {
			String candidate_name = "";
			for (int i = 0; i < emails.size(); i++) {
				resume = resume.replaceAll(emails.get(i), "");
			}
			for (int i = 0; i < emails.size(); i++) {
				for (int j = 0; j < 10; j++) {
					String[] words = resumeArray[j].replaceAll("\\s+", " ")
							.split(" ");
					for (int k = 0; k < words.length; k++) {
						double dis = DiceCoefficient.score(words[k], emails
								.get(i)
								.substring(0, emails.get(i).indexOf("@")));
						if (dis > 0.4) {
							candidate_name = words[k];
							if (k != 0) {
								String wordTokenizer[] = WhitespaceTokenizer.INSTANCE
										.tokenize(words[k - 1]);
								String[] tags = tagger.tag(wordTokenizer);
								if (tags.length > 0) {
									if (tags[0].equals("NN")
											|| tags[0].equals("NNP")
											|| tags.equals("NNPS")) {
										candidate_name = words[k - 1] + " "
												+ candidate_name;
									}
								}
							}
							if (k != words.length - 1) {
								String wordTokenizer1[] = WhitespaceTokenizer.INSTANCE
										.tokenize(words[k + 1]);
								String[] tags = tagger.tag(wordTokenizer1);
								if (tags.length > 0) {
									if (tags[0].equals("NN")
											|| tags[0].equals("NNP")
											|| tags.equals("NNPS")) {
										candidate_name = candidate_name + " "
												+ words[k + 1];
									}
								}
							}
							name.add(candidate_name);
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		}
		return name;
	}

	public String getEducationalDetails() {
		try {
			Set<String> keySet = layOuts.keySet();
			for (String key : keySet) {
				if (key.indexOf("Education") > -1
						|| key.indexOf("Academic") > -1
						|| key.indexOf("Qualifications") > -1
						|| key.indexOf("Study") > -1) {
					String details = layOuts.get(key);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return null;

	}

	@Override
	public String getId() {
		return id;
	}

	@Override
	public List<String> getHeadings() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getContent() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public boolean hasHeading(String heading) {
		// TODO Auto-generated method stub
		return false;
	}

	@Override
	public String getEducations() {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public String getAddress() {
		// TODO Auto-generated method stub
		return null;
	}
}
